package app

import command.CommandExec
import implicits.Implicits._
import org.apache.commons.io.FileUtils
import tool.Pojo.CommandData
import tool.Tool

import java.io.File
import scala.collection.immutable.SeqMap
import scala.collection.parallel.CollectionConverters._

/**
 * Created by yz on 29/10/2021
 */
object SingleMetRoc {

  val parentDir = new File("E:\\germline_mutation_database\\test")
  val dirMap = SeqMap(
    "Single_Var_Roc" -> "MMR突变",
  )

  def main(args: Array[String]): Unit = {
    val startTime = System.currentTimeMillis()
    //        dataMerge
    //        reName
    runScript
    resultDeal
    println((System.currentTimeMillis() - startTime) / 1000.0)

  }

  def isValidFileName(name: String, excludeSuffixs: List[String] = List.empty) = {
    val suffixs = List(".pdf", ".csv", ".svg", ".html", ".js", ".xlsx", "xls", "gml").filterNot { x =>
      excludeSuffixs.contains(x)
    }
    suffixs.exists(x => name.endsWith(x)) && (!name.startsWith("Rplots"))
  }

  def sameDirCopyRecu(sourceDir: File, targetDir: File) = {

    def loop(file: File): Unit = {
      for (file <- file.listFiles()) {
        if (file.isDirectory) {
          loop(file)
        } else {
          if (isValidFileName(file.getName)) {
            val filePath = file.getAbsolutePath
            val sourcePath = sourceDir.getAbsolutePath
            val targetFile = new File(targetDir, filePath.replace(sourcePath, ""))
            FileUtils.copyFile(file, targetFile)
          }

        }
      }
    }

    loop(sourceDir)

  }

  def resultDeal = {

    val resultDir = new File(parentDir, "result").createDirectoryWhenNoExist
    dirMap.foreach { case (dirName, columnName) =>
      val eachDir = new File(resultDir, dirName)
      val workspacePDir = new File(parentDir, dirName)
      val workspaceDir = new File(workspacePDir, "workspace")
      sameDirCopyRecu(workspaceDir, eachDir)
      val map = SeqMap("RF" -> "Random_Forest", "LR" -> "Logistic_Regression", "SVM" -> "Support_Vector_Machine",
        "cv" -> "Cross-Validation-Results")
      map.foreach { case (oldName, newName) =>
        eachDir.allFileAndDirs.filter(_.isDirectory).filter { x =>
          x.getName == oldName
        }.foreach { x =>
          val destDir = new File(x.getParentFile, newName).deleteIfExist
          x.dirMoveTo(destDir)
        }
      }
    }

  }

  def runScript = {
    dirMap.par.foreach { case (dirName, columnName) =>
      val dir = new File(parentDir, dirName).createDirectoryWhenNoExist
      val workspaceDir = new File(dir, "workspace")
      List("calculate_config.txt", "pr_plot_config.txt", "roc_plot_config.txt", "rfPlot_plot_config.txt",
        "color_solution_1.txt", "pca2D_plot_config.txt").
        foreach { fileName =>
          new File(parentDir, fileName).fileCopyToDir(workspaceDir)
        }
      val roCvPlotConfigFile = new File(parentDir, "rocCv_plot_config.txt")
      val roCvEachPlotConfigFile = new File(parentDir, "rocCvEach_plot_config.txt")
      val commandExec = CommandExec().exec { b =>
        val groupFile = new File(dir, "group.csv")
        val dataFile = new File(dir, "data_final_rename.csv")
        val command =
          s"""
             |cp ${groupFile.unixPath} group.csv
             |cp ${dataFile.unixPath} data.csv
             |${Tool.rScript} ${new File(Tool.rPath, "roc_calculate.R").unixPath}
             |${Tool.rScript} ${new File(Tool.rPath, "roc_plot.R").unixPath}
             |""".stripMargin
        CommandData(workspaceDir, List(command))
      }
      if (!commandExec.isSuccess) {
        System.err.println(commandExec.errorInfo)
      }
    }
  }

  def reName = {
    dirMap.foreach { case (dirName, columnName) =>
      val path = new File(parentDir, dirName)
      val dataPath = new File(path, "data.csv")
      val outPath = new File(path, "data_final_rename.csv")
      dataPath.csvLines.map { columns =>
        val name = columns.head.mySplit("(\\s| )+").mkString("_")
        name :: columns.tail
      }.toFile(outPath)
    }
  }

  def dataMerge = {
    val inPath = new File("E:\\germline_mutation")
    val dirNames = List(
      "Single_Var_Roc"
    )
    dirNames.foreach { case dirName =>
      val basicPath = dirName match {
        case "Single_Var_Roc" => new File(inPath, s"MMR 标准单因素AUC.xlsx")
      }
      val basicWithIdLines = basicPath.xlsxLines().lineSeqMap.zipWithIndex.map { case (map, i) =>
        SeqMap("SampleID" -> s"s${i}") ++ map
      }.csvLines.map { columns =>
        columns.map { column =>
          if (column == "NA" || column.isBlank) "N_A" else column
        }
      }
      val basicLines = basicWithIdLines.lineSeqMap.zipWithIndex.map { case (map, i) =>
        map.removedAll(List("MMR突变", "携带胚系突变", "raw_ID", "sampleID"))
      }.csvLines
      val columnName = dirMap(dirName)
      val outPath = new File(parentDir, dirName).createDirectoryWhenNoExist
      val groupPath = new File(outPath, "group.csv")
      val dataPath = new File(outPath, "data.csv")
      val outLines = basicLines
      outLines.transpose.filterNot(_.forall(_ == "N_A")).toFile(dataPath)
      basicWithIdLines.lineSeqMap.map { map =>
        map.filter { case (k, v) =>
          List("SampleID", columnName).contains(k)
        }
      }.csvLines.convertHeader(Map(columnName -> "Group")).toFile(groupPath)
    }
  }


}
